package xin.nick.system.service;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import xin.nick.common.core.constant.SystemConstants;
import xin.nick.common.core.util.BeanCopierUtil;
import xin.nick.system.domain.dto.SystemRoleCreateDTO;
import xin.nick.system.domain.dto.SystemRoleUpdateDTO;
import xin.nick.system.domain.query.SystemRoleQuery;
import xin.nick.system.domain.vo.SystemAuthorityVO;
import xin.nick.system.domain.vo.SystemRoleVO;
import xin.nick.system.entity.SystemAuthority;
import xin.nick.system.entity.SystemRole;
import xin.nick.system.manager.SystemAuthorityManager;
import xin.nick.system.mapper.SystemRoleMapper;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 系统-角色 服务实现类
 * </p>
 *
 * @author Nick
 * @since 2023-09-21
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class SystemRoleService extends ServiceImpl<SystemRoleMapper, SystemRole> {

    private final SystemAuthorityManager systemAuthorityManager;

    /**
     * 获取系统-角色详情
     *
     * @param roleId Long
     * @return SystemRoleVO
     */
    public SystemRoleVO getDetail(Long roleId) {
        Assert.notNull(roleId, SystemConstants.VALUE_IS_NOT_NULL_MSG_TEMPLATE, "roleId");
        SystemRole systemRole = getById(roleId);
        Assert.notNull(systemRole, "系统-角色不存在");

        SystemRoleVO systemRoleVO = BeanCopierUtil.copyProperties(systemRole, SystemRoleVO.class);

        // 补充权限信息
        List<SystemAuthority> authorityList = systemAuthorityManager.getAuthorityListByRoleId(roleId);
        List<SystemAuthorityVO> authorityVoList = BeanUtil.copyToList(authorityList, SystemAuthorityVO.class);
        systemRoleVO.setAuthorityList(authorityVoList);

        return systemRoleVO;
    }

    /**
     * 获取系统-角色列表
     *
     * @param query SystemRoleQuery
     * @return List<SystemRoleVO>
     */
    public List<SystemRoleVO> getList(SystemRoleQuery query) {

        LambdaQueryWrapper<SystemRole> queryWrapper = getListQueryWrapper(query);

        List<SystemRole> systemRoleList = list(queryWrapper);

        return BeanCopierUtil.copyToList(systemRoleList, SystemRoleVO.class);

    }

    /**
     * 获取系统-角色列表分页
     *
     * @param query SystemRoleQuery
     * @return Page<SystemRoleVO>
     */
    public Page<SystemRoleVO> getListPage(SystemRoleQuery query) {

        LambdaQueryWrapper<SystemRole> queryWrapper = getListQueryWrapper(query);

        Page<SystemRole> page = page(new Page<>(query.getCurrent(), query.getSize()), queryWrapper);

        return (Page<SystemRoleVO>) page.convert(entity -> BeanCopierUtil.copyProperties(entity, SystemRoleVO.class));
    }

    /**
     * 系统-角色添加
     *
     * @param dto SystemRoleCreateDTO
     * @return SystemRoleVO
     */
    public SystemRoleVO createSystemRole(SystemRoleCreateDTO dto) {
        SystemRole systemRole = BeanCopierUtil.copyProperties(dto, SystemRole.class);
        systemRole.setRoleId(null);
        save(systemRole);

        // 更新角色和权限关联
        systemAuthorityManager.updateRoleAuthorityList(systemRole.getRoleId(), dto.getAuthorityIdList());

        return getDetail(systemRole.getRoleId());
    }

    /**
     * 系统-角色更新
     *
     * @param dto SystemRoleUpdateDTO
     * @return SystemRoleVO
     */
    public SystemRoleVO updateSystemRole(SystemRoleUpdateDTO dto) {
        Long roleId = dto.getRoleId();
        Assert.notNull(dto.getRoleId(), SystemConstants.VALUE_IS_NOT_NULL_MSG_TEMPLATE, "roleId");
        SystemRole oldRole = getById(roleId);
        Assert.notNull(oldRole, "角色信息不存在");
        SystemRole systemRole = BeanCopierUtil.copyProperties(dto, SystemRole.class);
        updateById(systemRole);

        // 更新角色和权限关联
        systemAuthorityManager.updateRoleAuthorityList(roleId, dto.getAuthorityIdList());

        return getDetail(systemRole.getRoleId());
    }


    /**
     * 系统-角色删除
     *
     * @param roleId Long
     */
    public void deleteById(Long roleId) {
        Assert.notNull(roleId, "[roleId]不可为空");
        removeById(roleId);
    }


    /**
     * 系统-角色根据roleId批量删除
     *
     * @param roleIdList
     */
    public void deleteByIdList(List<Long> roleIdList) {
        if (CollUtil.isEmpty(roleIdList)) {
            return;
        }

        baseMapper.deleteBatchIds(roleIdList);
    }


    /**
     * 更新禁用状态
     *
     * @param roleId Long
     */
    public void updateDisabled(Long roleId) {
        Assert.notNull(roleId, "[roleId]不可为空");
        SystemRole systemRole = getById(roleId);
        Assert.notNull(systemRole, "系统角色信息不存在");

        Boolean disabled = Optional.ofNullable(systemRole.getDisabled()).orElse(false);
        SystemRole systemRoleUpdate = new SystemRole();
        systemRoleUpdate.setRoleId(roleId);
        systemRoleUpdate.setDisabled(!disabled);
        updateById(systemRoleUpdate);

    }

    /**
     * 获取列表查询条件
     *
     * @param query RoleQuery
     * @return LambdaQueryWrapper
     */
    private LambdaQueryWrapper<SystemRole> getListQueryWrapper(SystemRoleQuery query) {

        Long roleId = query.getRoleId();
        String roleKey = query.getRoleKey();
        String roleName = query.getRoleName();
        Boolean disabled = query.getDisabled();

        LambdaQueryWrapper<SystemRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(Objects.nonNull(roleId), SystemRole::getRoleId, roleId)
                .like(StringUtils.hasLength(roleKey), SystemRole::getRoleKey, roleKey)
                .like(StringUtils.hasLength(roleName), SystemRole::getRoleName, roleName)
                .eq(Objects.nonNull(disabled), SystemRole::getDisabled, disabled)
        ;

        queryWrapper.orderByDesc(SystemRole::getCreateTime);

        return queryWrapper;
    }


}
